home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Sound Cards
/
Programming Sound Cards.iso
/
sound_77
/
soundx.c
< prev
next >
Wrap
Text File
|
1995-01-01
|
7KB
|
365 lines
/*****************************************************************************
* Produces a code based on the "Soundex" method originally developed
* by M.K. Odell and R.C. Russell. Algorithm can be found on page
* 392 of Knuths' book 'Sorting and Searching', volume 3 of 'The Art
* of Computer Programming", Addison/Wesley publisher.
*
* Program Name: soundx.c
* coded by: Richard R. Schafer
*
*********** RELEASED INTO THE PUBLIC DOMAIN *********************************/
#include "nandef.h"
#include "extend.h"
#define ISALPHA(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
#define UPPER(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 32 : (c))
#define CODE_ALLOC 5 /** size of code sequence. 4 for code 1 for NIL**/
CLIPPER soundx()
{
/********************************************
* the type_defs: Boolean
* quant
* byte
* are defined in the include file "nandef.h"
********************************************/
Boolean error;
quant i; /* Both 'i' and 'b' are counters */
quant b;
quant name_size;
/* 'name' is where we put the parameter and 'short_name' is
where we'll put the string that doesn't contain anything
but ALPHA characters and 'code' is where we'll put the
soundex code that we are developing. */
byte *name;
byte *short_name;
byte *code;
/* intialize our code holder */
code = NULL;
/* If any of these are true, we didn't get a proper parameter */
error = (PCOUNT != 1 || !ISCHAR(1) || _parclen(1) == 0);
/* If we don't have any errors we'll continue otherwise dropout */
if (!error)
{
/* put the parameter passed into an array */
name = _parc(1);
/* determine the length the of parameter passed
and add 1 to hold the NIL byte
*/
name_size = (quant) (_parclen(1) + 1);
/* Now that we've got something to work with, lets
convert it to a soundex code. First we have to
allocate some memory for the code to be placed into.
We'll use the function '_exmgrab' to do just that.
*/
code = _exmgrab(CODE_ALLOC);
/* Now we'll initialize all of our arrays to hold NILs */
for (i = 0;i < name_size;i++)
{
short_name[i] = NIL;
}
for (i = 0;i < CODE_ALLOC;i++)
{
code[i] = NIL;
}
/* now let's get rid of everything we don't want
if it isn't an alpha character, we'll
get rid of it and convert all else to uppercase
*/
for (i = 0,b = 0;i < name_size; i++)
{
if (! ISALPHA(name[i]))
{
continue;
}
/* if it is a good character we'll place it into
another array to work from and increment the
second counter 'b' */
short_name[b] = UPPER(name[i]);
b++;
}
/* The first character gets used as is */
code[0] = short_name[0];
/* Then we convert the rest of the string to the proper
soundex numbers according to the algorithm. We'll stay in
the loop until such time as we have either run out of
characters to work with, or we have filled the code.
*/
for (i=1,b=1;(short_name[i] != NIL) && (b < (CODE_ALLOC - 1));i++ )
{
switch (short_name[i])
{
/* These are the characters that we want to skip,
so if we match one we'll just go round for the
next character
*/
case 'A':
case 'E':
case 'H':
case 'I':
case 'O':
case 'U':
case 'W':
case 'Y':
break;
/* If we match any of these, they're the good ones
so we'll assign a number to 'code' for them.
*/
case 'B':
case 'F':
case 'P':
case 'V':
code[b] = '1';
b++;
break;
case 'C':
case 'G':
case 'J':
case 'K':
case 'Q':
case 'S':
case 'X':
case 'Z':
code[b] = '2';
b++;
break;
case 'D':
case 'T': code[b] = '3';
b++;
break;
case 'L':
code[b] = '4';
b++;
break;
case 'M':
case 'N':
code[b] = '5';
b++;
break;
case 'R':
code[b] = '6';
b++;
break;
}
/* If we haven't gone beyond the last character in
'short_name'.
*/
if (short_name[i + 1] != NIL)
{
/* Check to see if the next character in the
array is the same as the one we just
evaluated, if so, we want to skip over it.
*/
if (short_name[i] == short_name[i + 1])
{
i++;
}
}
}
}
/* If the code isn't filled, we want to pad it with zeroes */
if (b < 4)
{
for (;b < 4;b++)
{
code[b] = '0';
}
}
/* Now we setup to return the code and then release the memory
that we allocated. We'll use the "_exmback" function to do that.
*/
if (!error)
_retc(code);
else
_retc("");
if (code)
_exmback(code,CODE_ALLOC);
}